import { User } from '../models/user';
import Project from '../models/project';

const insertErrorMessage = (htmlFile) => {
  const html = htmlFile.split('</head>');
  const metaDescription =
    'A web editor for p5.js, a JavaScript library with the goal of making coding accessible to artists, designers, educators, and beginners.'; // eslint-disable-line
  html[0] = `
    ${html[0]}
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="keywords" content="p5.js, p5.js web editor, web editor, processing, code editor" />
    <meta name="description" content="${metaDescription}" />
    <title>404 Page Not Found - p5.js Web Editor</title>
    <style>
      .header {
        position: fixed;
        height: 200px;
        width: 100%;
        z-index: 1;
        background: white;
        color: #ed225d;
        font-family: Montserrat, sans-serif;
        text-align: center;
        display: table;
      }
      .message-container {
        display: table-cell;
        vertical-align: middle;
      }
      .message {
        color: #6b6b6b;
        margin: 10px;
      }
      .home-link {
        color: #b5b5b5;
        text-decoration: none;
      }
      canvas {
        position: fixed;
        width: 100% !important;
        height: 100% !important;
      }
    </style>
    <link href='https://fonts.googleapis.com/css?family=Inconsolata' rel='stylesheet' type='text/css'>
    <link href='https://fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
    <link
      rel='shortcut icon'
      href='https://raw.githubusercontent.com/processing/p5.js-website-OLD/master/favicon.ico'
      type='image/x-icon'
    >
  `;
  const body = html[1].split('<body>');
  html[1] = `
    ${body[0]}
    <body>
      <div class="header">
        <div class="message-container">
          <h1>404 Page Not Found</h1>
          <h6 class="message">The page you are trying to reach does not exist.</h6>
          <h6 class="message">
            Please check the URL or return to the <a href="/" class="home-link">home page</a>.
          </h6>
        </div>
      </div>
    ${body[1]}
  `;
  return html.join('</head>');
};

export const get404Sketch = async () => {
  const errorMessage = insertErrorMessage(`<!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
      </head>
      <body>
      </body>
    </html>`);

  try {
    const p5User = await User.findOne({ username: 'p5' }).exec();

    if (!p5User) {
      return errorMessage;
    }

    const projects = await Project.find({ user: p5User._id }).exec();

    if (!projects.length) {
      return errorMessage;
    }

    const randomIndex = Math.floor(Math.random() * projects.length);
    const sketch = projects[randomIndex];

    // Get sketch files
    let htmlFile = sketch.files.find((file) => file.name.match(/.*\.html$/i))
      .content;
    const jsFiles = sketch.files.filter((file) => file.name.match(/.*\.js$/i));
    const cssFiles = sketch.files.filter((file) =>
      file.name.match(/.*\.css$/i)
    );
    const linkedFiles = sketch.files.filter((file) => file.url);

    const instanceMode = jsFiles
      .find((file) => file.name === 'sketch.js')
      .content.includes('Instance Mode');

    jsFiles.forEach((file) => {
      // Add js files as script tags
      const html = htmlFile.split('</body>');
      html[0] = `${html[0]}<script>${file.content}</script>`;
      htmlFile = html.join('</body>');
    });

    cssFiles.forEach((file) => {
      // Add css files as style tags
      const html = htmlFile.split('</head>');
      html[0] = `${html[0]}<style>${file.content}</style>`;
      htmlFile = html.join('</head>');
    });

    linkedFiles.forEach((file) => {
      // Add linked files as link tags
      const html = htmlFile.split('<head>');
      html[1] = `<link href=${file.url}>${html[1]}`;
      htmlFile = html.join('<head>');
    });

    // Add 404 html and position canvas
    htmlFile = insertErrorMessage(htmlFile);

    // Fix links to assets
    htmlFile = htmlFile.replace(
      /'assets/g,
      "'https://rawgit.com/processing/p5.js-website/main/dist/assets/examples/assets/"
    );
    htmlFile = htmlFile.replace(
      /"assets/g,
      '"https://rawgit.com/processing/p5.js-website/main/dist/assets/examples/assets/'
    );

    // Change canvas size
    htmlFile = htmlFile.replace(
      /createCanvas\(\d+, ?\d+/g,
      instanceMode
        ? 'createCanvas(p.windowWidth, p.windowHeight'
        : 'createCanvas(windowWidth, windowHeight'
    );
    return htmlFile;
  } catch (err) {
    console.error('Error retrieving 404 sketch:', err);
    throw err;
  }
};

export default get404Sketch;
